package com.blank.server;

import com.blank.model.Quiz;
import com.blank.model.TestReport;
import com.blank.model.User;
import com.blank.util.CommonUtil;

import java.io.*;
import java.util.LinkedList;

/**
 * 实现数据的存取，模拟数据访问层
 */
public class ServerDao {

    /**
     * 本地存储根目录
     */
    private static final String BASE_ROOT_DIR = "./ExamServer/src/";

    /**
     * 本地存储学员信息文件路径
     */
    private static final String USERS_LOCAL_FILE_PATH = "./ExamServer/src/userList.txt";

    /**
     * 本地存储考题信息文件路径
     */
    private static final String QUIZZES_LOCAL_FILE_PATH = "./ExamServer/src/QuizList.txt";


    /**
     * 管理员用户名和密码
     */
    private static final String ADMIN_USERNAME = "admin";
    private static final String ADMIN_PASSWORD = "123456";

    /**
     * List 集合存放所有学员账户信息
     */
    private LinkedList<User> userList = new LinkedList<>();

    /**
     * 目前用户
     */
    private User currentUser = new User();

    /**
     * List 集合存放所有考题信息
     */
    private LinkedList<Quiz> quizList = new LinkedList<>();

    /**
     * 实现管理员账号和密码的校验并返回结果
     */
    public boolean serverManagerCheck(User userAdmin) {
        // 判断管理员账户是否存在
        if (ADMIN_USERNAME.equals(userAdmin.getUsername()) && ADMIN_PASSWORD.equals(userAdmin.getPassword())) {
            // 存放目前的用户
            currentUser.setUsername(userAdmin.getUsername());
            currentUser.setPassword(userAdmin.getPassword());
            return true;
        } else {
            return false;
        }
    }

    /**
     * 实现学员账号和密码的校验并返回结果
     */
    public boolean serverUserCheck(User userStudent) {
        // 判断是否存在此学员账户
        if (userList.contains(userStudent)) {
            // 存放目前的用户
            currentUser.setUsername(userStudent.getUsername());
            currentUser.setPassword(userStudent.getPassword());
            return true;
        } else {
            return false;
        }
    }

    /**
     * 实现新增学员的功能并返回结果
     */
    public boolean serverAddStudent(User student) {
        // 判断是否存在跟新增学员相同用户名的账户
        if (userList.stream().noneMatch(user -> user.getUsername().equals(student.getUsername()))) {
            return userList.add(student);
        } else {
            return false;
        }
    }

    /**
     * 实现删除学员的功能并返回结果
     */
    public boolean serverDelStudent(User student) {
        // 遍历查找相同用户名的学员并删除
        for (User user : userList) {
            if (user.getUsername().equals(student.getUsername())) {
                return userList.remove(user);
            }
        }
        return false;
    }

    /**
     * 实现更新学员的功能并返回结果
     */
    public boolean serverUpdStudent(User student) {
        // 遍历查找相同用户名的学员并更新
        for (User user : userList) {
            if (user.getUsername().equals(student.getUsername())) {
                // 先删除再增加
                return userList.remove(user) && userList.add(student);
            }
        }
        return false;
    }

    /**
     * 实现查找学员的功能并返回查询的学员信息
     */
    public User serverGetStudent(User student) {
        // 遍历查找相同用户名的学员并返回
        for (User user : userList) {
            if (user.getUsername().equals(student.getUsername())) {
                return user;
            }
        }
        return null;
    }

    /**
     * 增加考题功能
     */
    public boolean serverAddQuiz(Quiz quiz) {
        return quizList.add(quiz);
    }

    /**
     * 遍历查找第一个包含 keyString 的考题，然后删除。
     */
    public boolean serverDelQuiz(String keyString) {
        // 遍历查找并删除
        for (Quiz quiz : quizList) {
            if (quiz.getContent().contains(keyString)) {
                return quizList.remove(quiz);
            }
        }
        return false;
    }

    /**
     * 遍历查找第一个包含 keyString 的考题，然后修改
     */
    public boolean serverUpdQuiz(String keyString, String choices, String answer) {
        // 遍历查找并更新
        for (Quiz quiz : quizList) {
            if (quiz.getContent().contains(keyString)) {
                quiz.setContent(keyString + choices);
                quiz.setAnswer(answer);
                return true;
            }
        }
        return false;
    }

    /**
     * 遍历查找第一个包含 keyString 的考题，然后返回查找到的考题
     */
    public Quiz serverGetQuiz(String keyString) {
        // 遍历查找考题并返回结果
        for (Quiz quiz : quizList) {
            if (quiz.getContent().contains(keyString)) {
                return quiz;
            }
        }
        return null;
    }

    /**
     * 导入考题
     */
    public boolean serverLoadQuizzes(LinkedList<Quiz> quizzes) {
        return quizList.addAll(quizzes);
    }

    /**
     * 修改密码
     */
    public boolean serverUpdPassword(String newPassword) {
        for (User user : userList) {
            if (user.equals(currentUser)) {
                user.setPassword(newPassword);
                currentUser.setPassword(newPassword);
                return true;
            }
        }
        return false;
    }

    /**
     * 保存考试成绩报告到数据库
     */
    public void saveTestReportToDatabase(TestReport testReport) {
        File file = new File(BASE_ROOT_DIR + testReport.getUsername());
        ObjectOutputStream fOos = null;
        try {
            // 如果存储文件不存在则创建文件
            if (!file.exists()) {
                System.out.println(file.createNewFile() ? "考试成绩报告文件创建成功" : "考试成绩报告文件创建失败");
            } else {
                System.out.println("考试成绩报告文件已存在，将被新报告文件覆盖");
            }
            // 建立对象输出流
            fOos = new ObjectOutputStream(new FileOutputStream(file));
            // 保存考试成绩报告信息
            fOos.writeObject(testReport);
            fOos.flush();
            System.out.println("已经保存考试成绩报告到数据库");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (null != fOos) {
                try {
                    fOos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 从数据库获取当前学员成绩报告
     */
    public TestReport getTestReportFromDatabase() {
        File file = new File(BASE_ROOT_DIR + getCurrentUser().getUsername());
        if (!file.exists()) {
            return null;
        }
        TestReport testReport = null;
        ObjectInputStream fOis = null;
        try {
            // 建立对象输入流
            fOis = new ObjectInputStream(new FileInputStream(file));
            // 读取信息
            testReport = CommonUtil.cast(fOis.readObject());
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        } finally {
            // 释放资源
            if (null != fOis) {
                try {
                    fOis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return testReport;
    }


    /**
     * 导入数据库的学员账户
     */
    public void loadUsersFromDatabase() {
        // 从本地文件读取所有学员账户信息到 List 集合中
        File file = new File(USERS_LOCAL_FILE_PATH);
        if (file.exists()) {
            ObjectInputStream fOis = null;
            try {
                // 建立对象输入流
                fOis = new ObjectInputStream(new FileInputStream(file));
                // 读取信息
                setUserList(CommonUtil.cast(fOis.readObject()));
                System.out.println("从数据库导入的学员信息如下：");
                System.out.println("-------------------------------------------");
                if (null == getUserList() || getUserList().isEmpty()) {
                    System.out.println("{空}");
                } else {
                    getUserList().forEach(System.out::println);
                }
                System.out.println("-------------------------------------------");
                System.out.println("学员账户信息已从数据库导入");
                System.out.println();
            } catch (IOException | ClassNotFoundException e) {
                e.printStackTrace();
            } finally {
                // 释放资源
                if (null != fOis) {
                    try {
                        fOis.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        } else {
            System.out.println("学员存储文件尚未创建，学员账户信息为空");
            System.out.println();
        }
    }

    /**
     * 导入数据库的考题
     */
    public void loadQuizzesFromDatabase() {
        // 从本地文件读取所有的考题到 List 集合中
        File file = new File(QUIZZES_LOCAL_FILE_PATH);
        if (file.exists()) {
            ObjectInputStream fOis = null;
            try {
                // 建立对象输入流
                fOis = new ObjectInputStream(new FileInputStream(file));
                // 读取信息
                setQuizList(CommonUtil.cast(fOis.readObject()));
                System.out.println("从数据库导入的考题信息如下：");
                System.out.println("-------------------------------------------");
                if (null == getQuizList() || getQuizList().isEmpty()) {
                    System.out.println("{空}");
                } else {
                    getQuizList().forEach(System.out::println);
                }
                System.out.println("-------------------------------------------");
                System.out.println("考题信息已从数据库导入");
                System.out.println();
            } catch (IOException | ClassNotFoundException e) {
                e.printStackTrace();
            } finally {
                // 释放资源
                if (null != fOis) {
                    try {
                        fOis.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        } else {
            System.out.println("考题存储文件尚未创建，考题信息为空");
            System.out.println();
        }
    }

    /**
     * 保存学员账户数据到数据库
     */
    public void saveUsersToDataBase() {
        // 保存 List 集合中所有学员账户信息到本地文件中
        File file = new File(USERS_LOCAL_FILE_PATH);
        ObjectOutputStream fOos = null;
        try {
            // 如果存储文件不存在则创建文件
            if (!file.exists()) {
                System.out.println(file.createNewFile() ? "学员存储文件创建成功" : "学员存储文件创建失败");
            }
            // 建立对象输出流
            fOos = new ObjectOutputStream(new FileOutputStream(file));
            // 保存信息
            fOos.writeObject(getUserList());
            fOos.flush();
            System.out.println("已经保存学员账户信息到数据库");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 释放资源
            if (null != fOos) {
                try {
                    fOos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 保存考题数据到数据库
     */
    public void saveQuizzesToDatabase() {
        // 保存 List 集合中所有考题信息到本地文件中
        File file = new File(QUIZZES_LOCAL_FILE_PATH);
        ObjectOutputStream fOos = null;
        try {
            // 如果存储文件不存在则创建文件
            if (!file.exists()) {
                System.out.println(file.createNewFile() ? "考题存储文件创建成功" : "考题存储文件创建失败");
            }
            // 建立对象输出流
            fOos = new ObjectOutputStream(new FileOutputStream(file));
            // 保存信息
            fOos.writeObject(getQuizList());
            fOos.flush();
            System.out.println("已经保存考题信息到数据库");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 释放资源
            if (null != fOos) {
                try {
                    fOos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 清空目前用户的信息
     */
    public void clearCurrentUser() {
        currentUser.setUsername(null);
        currentUser.setPassword(null);
    }

    public LinkedList<User> getUserList() {
        return userList;
    }

    public void setUserList(LinkedList<User> userList) {
        this.userList = userList;
    }

    public User getCurrentUser() {
        return currentUser;
    }

    public LinkedList<Quiz> getQuizList() {
        return quizList;
    }

    public void setQuizList(LinkedList<Quiz> quizList) {
        this.quizList = quizList;
    }
}
